/*
 * process.h
 *
 *  Created on: 20/04/2013
 *      Author: aceki
 */

#include "Definitions.h"

#ifndef PROCESS_H_
#define PROCESS_H_

/*
Pre: Recibe un puntero a la estructura de datos de control
Pos: devuelve true si quedan caracteres en la linea y si se alcanzó el fin de archivo.
	Caso contrario devuelve false.
*/
bool word_in_progress_and_eof_reached(t_data* data_arg){
	return ((data_arg->line_size>=1) && (feof(data_arg->input_file)));
}
/*
Pre: Recibe un puntero a la estructura de datos de control
Pos: devuelve true si no se alcanzó end of file y no hay ningun error. Caso contrario
devuelve false;
*/
bool not_end_and_not_error(t_data* data_arg){
	return ((!feof(data_arg->input_file))&&(!ferror(data_arg->input_file)));
}

bool char_es_numero(unsigned char car) {
	return((car>=48) && (car<=57));
}

bool char_es_letra(unsigned char car) {
	return (((car>=65) && (car<=90)) /* es mayuscula */
				|| ((car>=97) && (car<=122))); /* es minuscula */
}

bool es_numero(int index, unsigned char* word) {
	return char_es_numero(word[index]);
}

bool es_letra(int index, unsigned char* word) {
	return char_es_letra(word[index]);
}

bool no_eof_and_is_end_of_word(t_data* data_arg, unsigned char car) {
	return ((!feof(data_arg->input_file)) &&
			!char_es_numero(car) &&
			!char_es_letra(car));
}

bool end_of_word(t_data* data_arg, unsigned char* word, unsigned char car) {
	return ((!ferror(data_arg->input_file)) && (
			 no_eof_and_is_end_of_word(data_arg,car) ||
			word_in_progress_and_eof_reached(data_arg)));
}

void inc_words(t_data* data_arg, unsigned char* word) {
	if(data_arg->line_size>=1) { /*si hay algo para guardar*/
		++data_arg->size;
		data_arg->words=(data_arg->size==1)?((unsigned char**)calloc(data_arg->size,sizeof(char*))):
						((unsigned char**)realloc(data_arg->words,data_arg->size*sizeof(char*)));
		data_arg->words[data_arg->size-1]=word;
		data_arg->line_size=0;
	}
}

void store_char(t_data* data_arg,unsigned char** word,unsigned char Car){
	if (!end_of_word(data_arg,*word,Car)) {
		++data_arg->line_size;
		(*word)=(data_arg->line_size==1)?
				((unsigned char*)calloc(data_arg->line_size,sizeof(unsigned char))):
				((unsigned char*)realloc((*word),data_arg->line_size*sizeof(unsigned char)));
		(*word)[data_arg->line_size-1]=Car;
	}
	else {
		inc_words(data_arg,*word);
	}
}

/*
Pre:Recibe un puntero con la estrucutra de datos de control
Pos:Las lineas del archivo se encuentran cargadas en memoria. Devuelve STATUS_OK
	si la carga fué exitosa.
*/
int load_lines(t_data* data_arg){
	unsigned char* word=NULL;
	unsigned char Car=' ';
	do{
		if (fread(&Car,sizeof(unsigned char),1,data_arg->input_file)==1)
			store_char(data_arg,&word,Car);
	}
	while (not_end_and_not_error(data_arg));
	if (ferror(data_arg->input_file)) return BAD_READ;
	return STATUS_OK;
}

void show_lines(t_data* data_arg) {
	int i=0;
	for(i=0;i<data_arg->size;++i){
		printf("%s\n",data_arg->words[i]);
		free(data_arg->words[i]);
	}
	free(data_arg->words);
}

void Process_stream(t_data* data_arg,void (*sort)(char**,int)){
	sort((char**)data_arg->words,data_arg->size);
	show_lines(data_arg);
}


#endif /* PROCESS_H_ */
